package com.egao.common.module.validate.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.egao.common.core.Constants;
import com.egao.common.core.exception.BusinessException;
import com.egao.common.core.exception.ParameterException;
import com.egao.common.core.web.JsonResult;
import com.egao.common.core.web.PageParam;
import com.egao.common.module.cms.entity.Article;
import com.egao.common.module.student.entity.StudentSignSet;
import com.egao.common.module.student.service.StudentSignSetService;
import com.egao.common.module.validate.entity.ValidateRule;
import com.egao.common.module.validate.entity.ValidateRuleItem;
import com.egao.common.module.validate.enums.ValidateRuleItemCategoryEnum;
import com.egao.common.module.validate.enums.ValidateRuleItemRuleEnum;
import com.egao.common.module.validate.mapper.ValidateRuleMapper;
import com.egao.common.module.validate.service.ValidateRuleItemService;
import com.egao.common.module.validate.service.ValidateRuleService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ValidateRuleServiceImpl extends ServiceImpl<ValidateRuleMapper, ValidateRule> implements ValidateRuleService {

    @Resource
    private ValidateRuleItemService validateRuleItemService;
    @Resource
    private StudentSignSetService studentSignSetService;

    @Override
    public JsonResult validate(String module, Object object) {
        // 验证是否开启验证
        StudentSignSet studentSignSet = studentSignSetService.get();
        // 没有毕业去向配置 不验证规则
        if (studentSignSet == null) {
            return JsonResult.ok();
        }
        // 自定义表单规则验证关闭状态不验证
        if (1 == studentSignSet.getValidateForm()) {
            return JsonResult.ok();
        }

        // 结果集合
        List<ValidateRule> resultList = new ArrayList<>();

        // 查询模块所有规则
        List<ValidateRule> list = baseMapper.selectList(new LambdaQueryWrapper<ValidateRule>().eq(ValidateRule::getModule, module));

        // 没有规则返回空集合
        if (CollectionUtil.isEmpty(list)) {
            return JsonResult.ok();
        }

        // 查询所有的验证规则项
        List<ValidateRuleItem> itemList = validateRuleItemService.list(new LambdaQueryWrapper<ValidateRuleItem>().eq(ValidateRuleItem::getModule, module));

        // 开始验证全部规则
        for (ValidateRule rule : list) {
            // 规则结果
            ValidateRuleItem result = itemList.stream().filter(d -> rule.getId().equals(d.getValidateRuleId()) &&
                    ValidateRuleItemCategoryEnum.RESULT.getValue().equals(d.getCategory())
            ).findFirst().orElse(null);
            // 没有结果项不继续验证
            if (result == null) {
                continue;
            }

            // 规则项
            List<ValidateRuleItem> conditionList = itemList.stream().filter(d -> rule.getId().equals(d.getValidateRuleId()) &&
                    ValidateRuleItemCategoryEnum.CONDITION.getValue().equals(d.getCategory())
            ).collect(Collectors.toList());
            // 没有规则项不继续验证
            if (CollectionUtil.isEmpty(conditionList)) {
                continue;
            }

            // 规则项分组 同组规则分到一起
            Map<Integer, List<ValidateRuleItem>> conditionMap = conditionList.stream().collect(Collectors.groupingBy(ValidateRuleItem::getGrouping));

            // 规则验证 一组中所有规则都满足则需要验证结果
            int validateCount = 0;
            for (Map.Entry<Integer, List<ValidateRuleItem>> entry : conditionMap.entrySet()) {
                // 一组规则中的所有规则项
                List<ValidateRuleItem> validateRuleItemList = entry.getValue();
                boolean groupBool = true;
                for (ValidateRuleItem item : validateRuleItemList) {
                    // 需要验证的值
                    Object o = BeanUtil.getFieldValue(object, item.getFieldName());
                    // 条件比对
                    groupBool = validate(item.getRule(), item.getFieldValue(), o);
                    // 条件不成立 退出循环
                    if (!groupBool) {
                        break;
                    }
                }
                // 一组中条件验证完成后还是true则可以对结果进行验证
                if (groupBool) {
                    validateCount++;
                    break;
                }
            }

            // 条件不成立 不验证结果
            if (validateCount == 0) {
                continue;
            }

            // 验证结果
            Object obj = BeanUtil.getFieldValue(object, result.getFieldName());
            boolean resultBool = validate(result.getRule(), result.getFieldValue(), obj);
            if (!resultBool) {
                resultList.add(rule);
            }
        }

        // 无错误 返回通过
        if (CollectionUtil.isEmpty(resultList)) {
            return JsonResult.ok();
        }

        return JsonResult.error(Constants.RESULT_PAUSE_CODE, "验证失败").setData(resultList);
    }

    /**
     * 验证条件
     * @param rule 规则
     * @param value 条件值
     * @param o 结果
     * @return boolean
     */
    private boolean validate(Integer rule, String value, Object o) {
        List<String> values = Arrays.asList(value.split(","));
        String result = o.toString();
        if (ValidateRuleItemRuleEnum.DY.getValue().equals(rule)) {
            return values.stream().filter(result::equals).count() > 0L;
        }
        if (ValidateRuleItemRuleEnum.BDY.getValue().equals(rule)) {
            return values.stream().filter(result::equals).count() == 0L;
        }
        if (ValidateRuleItemRuleEnum.BH.getValue().equals(rule)) {
            return values.stream().filter(result::contains).count() > 0L;
        }
        if (ValidateRuleItemRuleEnum.BBH.getValue().equals(rule)) {
            return values.stream().filter(result::contains).count() == 0L;
        }
        if (ValidateRuleItemRuleEnum.FK.getValue().equals(rule)) {
            return !StrUtil.isBlank(result);
        }
        if (ValidateRuleItemRuleEnum.BXK.getValue().equals(rule)) {
            return StrUtil.isBlank(result);
        }
        if (ValidateRuleItemRuleEnum.QBDY.getValue().equals(rule)) {
            if (StrUtil.isBlank(result)) {
                return false;
            }
            return !result.startsWith(value);
        }
        if (ValidateRuleItemRuleEnum.HBDY.getValue().equals(rule)) {
            if (StrUtil.isBlank(result)) {
                return false;
            }
            return !result.endsWith(value);
        }

        return false;
    }


    @Override
    public List<ValidateRule> listPage(PageParam<ValidateRule> pageParam) {
        return baseMapper.listPage(pageParam);
    }

    @Override
    public JsonResult insertValidateRule(ValidateRule validateRule) {
        verifyParam(validateRule);
        if (!save(validateRule)) {
            return JsonResult.error("验证规则添加失败");
        }
        return JsonResult.ok("验证规则添加成功");
    }

    @Override
    public JsonResult updateValidateRule(ValidateRule validateRule) {
        verifyParam(validateRule);
        if (!updateById(validateRule)) {
            return JsonResult.error("验证规则修改失败");
        }
        return JsonResult.ok("验证规则修改成功");
    }

    @Override
    public JsonResult deleteValidateRule(Integer id) {
        if (id == null) {
            throw new ParameterException("参数对象为空");
        }
        if (!removeById(id)) {
            return JsonResult.error("验证规则删除失败");
        }
        return JsonResult.ok("验证规则删除成功");
    }

    @Override
    public JsonResult getValidateRuleRelById(Integer id) {
        ValidateRule validateRule = getById(id);
        if (Objects.isNull(validateRule)) {
            throw new BusinessException("验证规则不存在");
        }
        LambdaQueryWrapper<ValidateRuleItem> lqw = Wrappers.lambdaQuery(ValidateRuleItem.class)
                .eq(ValidateRuleItem::getValidateRuleId, id);
        List<ValidateRuleItem> list = validateRuleItemService.list(lqw);
        validateRule.setValidateRuleItemList(list);
        return JsonResult.ok().setData(validateRule);
    }

    /**
     * 验证参数
     * @param validateRule
     * @return boolean
     */
    private void verifyParam(ValidateRule validateRule) {
        if (Objects.isNull(validateRule)) {
            throw new ParameterException("参数对象不能为空");
        }
        if (Objects.isNull(validateRule.getModule()) || StrUtil.isBlank(validateRule.getModule())) {
            throw new ParameterException("验证模块不能为空");
        }
        if (Objects.isNull(validateRule.getTitleCode()) || StrUtil.isBlank(validateRule.getTitleCode())) {
            throw new ParameterException("规则标题显示code不能为空");
        }
        if (Objects.isNull(validateRule.getTitleText()) || StrUtil.isBlank(validateRule.getTitleText())) {
            throw new ParameterException("规则标题显示文本不能为空");
        }
        if (Objects.isNull(validateRule.getResultCode()) || StrUtil.isBlank(validateRule.getResultCode())) {
            throw new ParameterException("结果标题显示code不能为空");
        }
        if (Objects.isNull(validateRule.getResultText()) || StrUtil.isBlank(validateRule.getResultText())) {
            throw new ParameterException("结果标题显示文本不能为空");
        }
    }

}
